bug fixes to tap and parallax.
Signed-off-by: andrew.warfield@cl.cam.ac.uk
(blktap_mode & BLKTAP_MODE_COPY_FE) ) {
blktap_write_ctrl_ring(msg);
+ blktap_kick_user();
}
switch ( msg->subtype )
/*-----[ Ring helpers ]---------------------------------------------------*/
+static void maybe_trigger_blktap_schedule(void);
+
inline int write_resp_to_fe_ring(blkif_t *blkif, blkif_response_t *rsp)
{
blkif_response_t *resp_d;
RING_PUSH_RESPONSES(&blkif->blk_ring);
notify_via_evtchn(blkif->evtchn);
DPRINTK("notified FE(dom %u)\n", blkif->domid);
+
+ /* We just feed up a batch of request slots... */
+ maybe_trigger_blktap_schedule();
}
add_to_blkdev_list_tail(blkif);
blkif_put(blkif);
}
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- /* Push the batch through to disc. */
- run_task_queue(&tq_disk);
-#endif
}
}
-static void maybe_trigger_blkio_schedule(void)
+static void maybe_trigger_blktap_schedule(void)
{
/*
* Needed so that two processes, who together make the following predicate
*/
smp_mb();
- if ( (NR_ACTIVE_REQS < (MAX_ACTIVE_REQS)) && /* XXX!!! was M_A_R/2*/
+ if ( (NR_ACTIVE_REQS < (MAX_ACTIVE_REQS/2)) &&
!list_empty(&blkio_schedule_list) )
wake_up(&blkio_schedule_wait);
}
blkif_t *blkif = dev_id;
add_to_blkdev_list_tail(blkif);
- maybe_trigger_blkio_schedule();
+ maybe_trigger_blktap_schedule();
return IRQ_HANDLED;
}
int more_to_do = 0;
int notify_be = 0, notify_user = 0;
- DPRINTK("PT got FE interrupt.\n");
-
if (NR_ACTIVE_REQS == MAX_ACTIVE_REQS) return 1;
/* lock both rings */
#else
#define DPRINTF(_f, _a...) ((void)0)
#endif
-#define DEBUG_RING_IDXS 1
+#define DEBUG_RING_IDXS 0
#define POLLRDNORM 0x040
response_hook_t *rsp_hook;
ctrl_hook_t *ctrl_hook;
- printf("Control Hooks:\n");
+ DPRINTF("Control Hooks:\n");
ctrl_hook = ctrl_hook_chain;
while (ctrl_hook != NULL)
{
- printf(" [0x%p] %s\n", ctrl_hook->func, ctrl_hook->name);
+ DPRINTF(" [0x%p] %s\n", ctrl_hook->func, ctrl_hook->name);
ctrl_hook = ctrl_hook->next;
}
- printf("Request Hooks:\n");
+ DPRINTF("Request Hooks:\n");
req_hook = request_hook_chain;
while (req_hook != NULL)
{
- printf(" [0x%p] %s\n", req_hook->func, req_hook->name);
+ DPRINTF(" [0x%p] %s\n", req_hook->func, req_hook->name);
req_hook = req_hook->next;
}
- printf("Response Hooks:\n");
+ DPRINTF("Response Hooks:\n");
rsp_hook = response_hook_chain;
while (rsp_hook != NULL)
{
- printf(" [0x%p] %s\n", rsp_hook->func, rsp_hook->name);
+ DPRINTF(" [0x%p] %s\n", rsp_hook->func, rsp_hook->name);
rsp_hook = rsp_hook->next;
}
}
ph->events = events;
ph->active = 1;
- printf("Added fd %d at ph index %d, now %d phs.\n", fd, ph_cons-1,
+ DPRINTF("Added fd %d at ph index %d, now %d phs.\n", fd, ph_cons-1,
nr_pollhooks());
return 0;
break;
}
- printf("Removed fd %d at ph index %d, now %d phs.\n", fd, i,
+ DPRINTF("Removed fd %d at ph index %d, now %d phs.\n", fd, i,
nr_pollhooks());
}
void __attribute__ ((constructor)) blktaplib_init(void)
{
- printf("[[ C O N S T R U C T O R ]]\n");
pollhook_init();
}
/* assign the rings to the mapped memory */
csring = (ctrl_sring_t *)blktap_mem;
- BACK_RING_INIT(&ctrl_ring, csring, CONTROL_RING_MEM);
+ BACK_RING_INIT(&ctrl_ring, csring, PAGE_SIZE);
sring = (blkif_sring_t *)((unsigned long)blktap_mem + PAGE_SIZE);
FRONT_RING_INIT(&be_ring, sring, PAGE_SIZE);
sring = (blkif_sring_t *)((unsigned long)blktap_mem + (2 *PAGE_SIZE));
BACK_RING_INIT(&fe_ring, sring, PAGE_SIZE);
- mmap_vstart = (unsigned long)blktap_mem + (BLKTAP_RING_PAGES << PAGE_SHIFT);
-
- printf("fe_ring mapped at: %p\n", fe_ring.sring);
- printf("be_ring mapped at: %p\n", be_ring.sring);
+ mmap_vstart = (unsigned long)blktap_mem +(BLKTAP_RING_PAGES << PAGE_SHIFT);
ioctl(fd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE );
}
void got_sig_int() {
- printf("quitting -- returning to passthrough mode.\n");
+ DPRINTF("quitting -- returning to passthrough mode.\n");
if (fd > 0) ioctl(fd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_PASSTHROUGH );
+ close(fd);
+ fd = 0;
exit(0);
}
blkif->domid = domid;
blkif->handle = handle;
blkif->status = DISCONNECTED;
-/*
- spin_lock_init(&blkif->vbd_lock);
- spin_lock_init(&blkif->blk_ring_lock);
- atomic_set(&blkif->refcnt, 0);
-*/
+
pblkif = &blkif_hash[BLKIF_HASH(domid, handle)];
while ( *pblkif != NULL )
{
if ( ((*pblkif)->domid == domid) && ((*pblkif)->handle == handle) )
{
- DPRINTF("Could not create blkif: already exists\n");
+ DPRINTF("Could not create blkif: already exists (%d,%d)\n",
+ domid, handle);
create->status = BLKIF_BE_STATUS_INTERFACE_EXISTS;
free(blkif);
return;
destroy:
*pblkif = blkif->hash_next;
- /* destroy_all_vbds(blkif); */
free(blkif);
destroy->status = BLKIF_BE_STATUS_OKAY;
}
vdip = &(*vdip)->next;
*vdip = vdi;
- DPRINTF("vbd_grow: happy return!\n");
+ DPRINTF("blkif_create succeeded\n");
create->status = BLKIF_BE_STATUS_OKAY;
}
+void vbd_destroy(blkif_be_vbd_destroy_t *destroy)
+{
+ blkif_t *blkif;
+ vdi_t *vdi, **vdip;
+ blkif_vdev_t vdevice = destroy->vdevice;
+
+ blkif = blkif_find_by_handle(destroy->domid, destroy->blkif_handle);
+ if ( blkif == NULL )
+ {
+ DPRINTF("vbd_destroy attempted for non-existent blkif (%u,%u)\n",
+ destroy->domid, destroy->blkif_handle);
+ destroy->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
+ return;
+ }
+
+ vdip = &blkif->vdi_hash[VDI_HASH(vdevice)];
+ while ((*vdip != NULL) && ((*vdip)->vdevice != vdevice))
+ vdip = &(*vdip)->next;
+
+ if (*vdip != NULL)
+ {
+ vdi = *vdip;
+ *vdip = vdi->next;
+ vdi_put(vdi);
+ }
+
+}
+
int parallax_control(control_msg_t *msg)
{
domid_t domid;
goto parse_error;
vbd_create((blkif_be_vbd_create_t *)msg->msg);
break;
+
+ case CMSG_BLKIF_BE_VBD_DESTROY:
+ if ( msg->length != sizeof(blkif_be_vbd_destroy_t) )
+ goto parse_error;
+ vbd_destroy((blkif_be_vbd_destroy_t *)msg->msg);
+ break;
+
+ case CMSG_BLKIF_BE_CONNECT:
+ case CMSG_BLKIF_BE_DISCONNECT:
+ /* we don't manage the device channel, the tap does. */
+ break;
+
+ default:
+ goto parse_error;
}
return 0;
parse_error:
sector, blkif_first_sect(req->frame_and_sects[i]),
blkif_last_sect (req->frame_and_sects[i]),
vblock, gblock, size);
-
+
/* XXX: For now we just freak out if they try to write a */
/* non block-sized, block-aligned page. */
blkif_response_t *rsp;
domid_t dom = ID_TO_DOM(req->id);
blkif_t *blkif = blkif_find_by_handle(dom, 0);
-
- //DPRINTF("parallax_request: req=%p, dom=%d, blkif=%p\n", req, dom, blkif);
if (blkif == NULL)
goto err;
return parallax_write(req, blkif);
} else {
+ printf("Unknown request message type!\n");
/* Unknown operation */
goto err;
}
err:
rsp = (blkif_response_t *)req;
- rsp->id = req->id;
rsp->operation = req->operation;
+ rsp->id = req->id;
rsp->status = BLKIF_RSP_ERROR;
return BLKTAP_RESPOND;
}
void __rcache_init(void)
{
int i;
-printf("rcache_init!\n");
for (i=0; i<RCHASH_SIZE; i++)
rcache[i] = NULL;
return vdi;
}
+/* vdi_get and vdi_put currently act more like alloc/free -- they don't
+ * do refcount-based allocation.
+ */
vdi_t *vdi_get(u64 vdi_id)
{
u64 vdi_blk;
return vdi;
}
+void vdi_put(vdi_t *vdi)
+{
+ free(vdi->radix_lock);
+ freeblock(vdi);
+}
+
u64 vdi_lookup_block(vdi_t *vdi, u64 vdi_block, int *writable)
{
u64 gblock;
snap_id_t snap; /* next snapshot slot for this VDI */
struct vdi *next; /* used to hash-chain in blkif. */
blkif_vdev_t vdevice; /* currently mounted as... */
- struct radix_lock *radix_lock;/* per-line L1 RW lock for parallel reqs */
+ struct radix_lock *radix_lock;/* per-line L1 RW lock for parallel reqs */
char name[VDI_NAME_SZ];/* human readable vdi name */
} vdi_t;
int __init_vdi(void);
vdi_t *vdi_get(u64 vdi_id);
+void vdi_put(vdi_t *vdi);
vdi_registry_t *get_vdi_registry(void);
vdi_t *vdi_create(snap_id_t *parent_snap, char *name);
u64 vdi_lookup_block(vdi_t *vdi, u64 vdi_block, int *writable);